package src;

import java.util.Random;

import javax.vecmath.Matrix3d;

/**
 * La classe contiente metodi usati
 * da diverse classi.
 *
 */
public class Basic {

	final static double TWO_TIMES_PI = 2 * Math.PI;
	final static double EPSILON = 1e-10;
	final static int RAND_MAX=32767;

	public static double set_min(double x,double y)
	{
		if(x>y) return y;
		return x;
	}

	public static double set_max(double x,double y)
	{
		if(x<y) return y;
		return x;
	}

	/**
	 * Metodo per la generazione casuale di un quaternione
	 * @param x0
	 * @param t1
	 * @param t2
	 * @return
	 */
	public static Quaternion random(double x0, double t1, double t2) {
		double r1 = Math.sqrt(1 - x0), r2 = Math.sqrt(x0);
		double c1 = Math.cos(t1), s1 = Math.sin(t1);
		double c2 = Math.cos(t2), s2 = Math.sin(t2);
		return new Quaternion(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
	}

	public static Quaternion random() {
		double x0 = rnd();
		double r1 = Math.sqrt(1 - x0), r2 = Math.sqrt(x0);
		double t1 = TWO_TIMES_PI * rnd(), t2 = TWO_TIMES_PI * rnd();
		double c1 = Math.cos(t1), s1 = Math.sin(t1);
		double c2 = Math.cos(t2), s2 = Math.sin(t2);

		return new Quaternion(s1 * r1, c1 * r1, s2 * r2, c2 * r2);
	}

	public static double rnd() { return Math.random(); }

	public static boolean   eqz(double x) { return Math.abs(x) < EPSILON; }

	public static double rowdot(Matrix3d m,int i, double[] v) {
		return m.getElement(0,i) * v[0] + m.getElement(1,i) * v[1] + m.getElement(2,i) * v[2];
	}

	public static double dot(Matrix3d m,int i, double[] v) {
		double[] temp= new double[3];
		m.getRow(i, temp);
		return temp[0]*v[0]+temp[1]*v[1]+temp[2]*v[2];
	}

	public static double[] cross(double[]a, double[] b)
	{
		double[] v= new double[3];
		v[0]=a[1]*b[2] - a[2]*b[1];
		v[1]=a[2]*b[0] - a[0]*b[2];
		v[2]=a[0]*b[1] - a[1]*b[0];
		return v;
	}

	public static boolean approxZero(double[] v)
	{
		return Basic.eqz(v[0]) && Basic.eqz(v[1]) && Basic.eqz(v[2]);
	}

	public static int closestAxis(double[] vector)
	{
		double[] a= new double[2];
		a[0] = Math.abs(vector[0]);
		a[1] = Math.abs(vector[1]);
		int axis = a[0] < a[1] ? 1 : 0;
		return a[axis] < Math.abs(vector[2]) ? 2 : axis;
	}

	public static double[] divNormal(double[] vect)
	{
		double[] temp = new double[3];
		double length = 0;
		length = Math.sqrt(vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2]);
		temp[0]=vect[0]/length;
		temp[1]=vect[1]/length;
		temp[2]=vect[2]/length;
		return temp;
	}
}
